poj1830 开关问题 发表于 2018-04-16 1234567891011121314151617高斯消元解决异或方程组异或方程组为a11·x1^a12·x2^...^a1n·xn=y1a21·x1^a22·x2^...^a2n·xn=y2...an1·x1^an2·x2^...^ann·xn=yn增广矩阵为a11 a12 ... a1n y1a21 a22 ... a2n y2...an1 an2 ... ann yn所有a,x,y均是0/1消元的时候将某一行加到另一行相当于某一行异或到另一行(因为是模2的!!)bitset空间消耗更小但是bitset的每一位是1bit,不是c++基本类型,不能^=(a[i]^=j不行,a^=j可以) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778#include<iostream>#include<cstdio>#include<cstring>#include<climits>#include<queue>#include<bitset>#define mp make_pair#define pb push_backusing namespace std;typedef long long LL;typedef pair<int,int> PII;inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;}const int N=38;int T;int n,a[N][N],x,y,ans;inline int gauss(){ register int i,j,k,tmp;//i为行,j为列 for(i=1,j=1;j<=n;++j){ if(a[i][j]==0){ for(tmp=i+1;tmp<=n;++tmp){ if(a[tmp][j]) break; } if(tmp>n) continue; for(k=j;k<=n+1;++k){ swap(a[tmp][k],a[i][k]); } } for(k=1;k<=n;++k){ if(k!=i&&a[k][j]){ for(tmp=j;tmp<=n+1;++tmp){ a[k][tmp]^=a[i][tmp]; } } } ++i; } for(j=i;j<=n;++j){ if(a[j][n+1]) return -1; } return 1<<(n-i+1);}int main(){ T=read(); while(T--){ memset(a,0,sizeof(a)); n=read(); for(int i=1;i<=n;++i){ a[i][n+1]=read(); } for(int i=1;i<=n;++i){ a[i][n+1]^=read(); } for(int i=1;i<=n;++i){ a[i][i]=1; } while(1){ x=read();y=read(); if(x==0&&y==0) break; a[y][x]=1; } ans=gauss(); if(ans==-1){ puts("Oh,it's impossible~!!"); } else{ printf("%d\n",ans); } } return 0;} 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#include<iostream>#include<cstdio>#include<cstring>#include<climits>#include<queue>#include<bitset>#define mp make_pair#define pb push_backusing namespace std;typedef long long LL;typedef pair<int,int> PII;inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;}const int N=38;int T;int n,x,y,ans;bitset<N> a[N];inline int gauss(){ register int i=1,j,k,tmp;//i为行,j为列 for(j=1;j<=n;++j){ if(a[i][j]==0){ for(tmp=i+1;tmp<=n;++tmp){ if(a[tmp][j]) break; } if(tmp>n) continue; swap(a[tmp],a[i]); } for(k=1;k<=n;++k){ if(k!=i&&a[k][j]){ a[k]^=a[i]; } } ++i; } for(j=i;j<=n;++j){ if(a[j][n+1]) return -1; } return 1<<(n-i+1);}int main(){ T=read(); while(T--){ for(int i=1;i<=n;++i){ a[i].reset(); } n=read(); for(int i=1;i<=n;++i){ a[i][n+1]=read(); } for(int i=1;i<=n;++i){ a[i][n+1]=a[i][n+1]^read(); } for(int i=1;i<=n;++i){ a[i][i]=1; } while(1){ x=read();y=read(); if(x==0&&y==0) break; a[y][x]=1; } ans=gauss(); if(ans==-1){ puts("Oh,it's impossible~!!"); } else{ printf("%d\n",ans); } } return 0;}